package com.hunk.core.auth.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.object.MappingSqlQuery;
import org.springframework.jdbc.object.SqlUpdate;
import org.springframework.stereotype.Repository;

import com.hunk.core.auth.entity.User;
import com.hunk.core.dao.BaseDaoSpringJdbc;
import com.hunk.core.dao.CrudDao;

/**
 * Description :<br>
 * 
 * @author HunkDeng
 * @since 2013-4-13
 */

public class UserDao extends BaseDaoSpringJdbc<User> implements CrudDao<String,User> {
	
	@Resource
	public void setJb(JdbcTemplate jb) {
	 super.setJdbcTemplate(jb);
	}
	
	public final static String SYS_USER = "sys_user";
	@Autowired
	DataSource dataSource;
	
	@Override
	public void delete(String ID) throws SQLException {
		throw new UnsupportedOperationException();
	}
	
	public void delete(User user) throws SQLException {
		update("delete from " + SYS_USER + " WHERE ID = :id", user);
	}
	@Override
	public User get(String ID) throws SQLException {
		return userQuery.findObject(ID);
	}	
	@Override
	public User save(User entity) throws SQLException {
		entity.setId(UUID.randomUUID().toString());
		userInsert.insert(entity);
		return null;
	}
	@Override
	public User update(User entity) throws SQLException {
		update("UPDATE " + SYS_USER +
				" SET " +
				" USERNAME=:username, PASSWORD=:password, REALNAME=:realname," +
				" EMAIL=:email, PHONE=:phone, ADDRESS=:address, MOBILE=:mobile," +
				" ENABLED=:enabled, REMARK=:remark " +
				" WHERE ID=:id", entity);
		return entity;
	}	
	private UserInsert userInsert;
	private UserQuery userQuery;
	
	@PostConstruct
	public void init() {
		this.userQuery = new UserQuery(dataSource);
		this.userInsert = new UserInsert(this.dataSource);
	}
	
	private class UserInsert extends SqlUpdate {
		public UserInsert(DataSource ds) {
			super(ds, 
					"INSERT INTO "+ SYS_USER + "(`ID`,`USERNAME`,`PASSWORD`,`REALNAME`,`EMAIL`,`PHONE`,`ADDRESS`,`MOBILE`,`ENABLED`,`REMARK`)" +
					" VALUES(:ID,:USERNAME,:PASSWORD,:REALNAME,:EMAIL,:PHONE,:ADDRESS,:MOBILE,:ENABLED,:REMARK)");
			declareParameter(new SqlParameter("ID", Types.VARCHAR));
			declareParameter(new SqlParameter("USERNAME", Types.VARCHAR));
			declareParameter(new SqlParameter("PASSWORD", Types.VARCHAR));
			declareParameter(new SqlParameter("REALNAME", Types.VARCHAR));
			declareParameter(new SqlParameter("EMAIL", Types.VARCHAR));
			declareParameter(new SqlParameter("PHONE", Types.VARCHAR));
			declareParameter(new SqlParameter("ADDRESS", Types.VARCHAR));
			declareParameter(new SqlParameter("MOBILE", Types.VARCHAR));
			declareParameter(new SqlParameter("ENABLED", Types.VARCHAR));
			declareParameter(new SqlParameter("REMARK", Types.VARCHAR));
			compile();
		}
		public void insert(User user) {
			Map<String,String> params = new HashMap<String, String>();
			params.put("ID", user.getId());
			params.put("USERNAME", user.getUsername());
			params.put("PASSWORD", user.getPassword());
			params.put("REALNAME", user.getRealname());
			params.put("EMAIL", user.getEmail());
			params.put("PHONE", user.getPhone());
			params.put("ADDRESS", user.getAddress());
			params.put("MOBILE", user.getMobile());
			params.put("ENABLED", user.isEnabled() ? "1":"0");
			params.put("REMARK", user.getRemark());
			super.updateByNamedParam(params);
		}
	}
	
	private class UserQuery extends MappingSqlQuery<User> {

		public UserQuery(DataSource ds) {
			super(
				ds,
				" SELECT ID,USERNAME,PASSWORD,REALNAME,EMAIL,PHONE,ADDRESS,MOBILE,ENABLED,REMARK" +
				" FROM " + SYS_USER + 
				" WHERE ID = ?");
			declareParameter(new SqlParameter(Types.VARCHAR));
			compile();
			getSql();
		}
		
		@Override
		protected User mapRow(ResultSet rs, int rowNum) throws SQLException {
			User user = new User();
			user.setId(rs.getString("ID"));
			user.setUsername(rs.getString("USERNAME"));
			user.setPassword(rs.getString("PASSWORD"));
			user.setRealname(rs.getString("REALNAME"));
			user.setEmail(rs.getString("EMAIL"));
			user.setPhone(rs.getString("PHONE"));
			user.setAddress(rs.getString("ADDRESS"));
			user.setMobile(rs.getString("MOBILE"));
			user.setEnabled("1".equals(rs.getString("ENABLED"))? true:false);
			user.setRemark(rs.getString("REMARK"));
			return user;
		}		
	}
	
	public User getUserByName(User user) {
		return getJavaBean("select * from " + SYS_USER + " where username = :username",
				User.class, user);
	}
	
}
